package engine

import "log"

type ConcurrentEngine struct {
	Scheduler   Scheduler
	WorkerCount int
	ItemChan    chan Item
}


type Scheduler interface {
	ReadyNotifier
	Submit(request Request)
	WorkerChan() chan Request
	Run()
}

type ReadyNotifier interface {
	WorkerReady(chan Request)
}

func (engine *ConcurrentEngine) Run(seeds ...Request) {

	//in := make(chan Request)
	out := make(chan ParseResult)
	engine.Scheduler.Run()

	for i := 0; i < engine.WorkerCount; i++ {
		createWorker(engine.Scheduler.WorkerChan(), out, engine.Scheduler)
	}

	for _, r := range seeds {
		engine.Scheduler.Submit(r)
	}

	for {
		result := <-out

		for _, item := range result.Items {
			go func(item Item) {
				engine.ItemChan <- item
			}(item)
		}

		for _, request := range result.Requests {
			engine.Scheduler.Submit(request)
		}
	}

}


func createWorker(in chan Request, out chan ParseResult, ready ReadyNotifier) {
	go func() {
		for {
			ready.WorkerReady(in)
			request := <-in


			if 1 == visitor(request.Url){
				log.Printf("visited %s ", request.Url)
				continue
			}
			result, err := worker(request)
			if err != nil {
				continue
			}
			out <- result
		}
	}()
}

